/*
 * 本类作用：mina初始化及启动（上一步：程序界面初始化DataReceiveFrame，下一步：mina框架过滤器MinaServerIOFilter）
 * 
 * 作者：袁小杰
 * 博客：http://blog.csdn.net/undoner
 * GIT：https://git.oschina.net/undoner
 * QQ：15137281
 * 
 */
package org.mina.server;

import java.io.File;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSessionConfig;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.executor.ExecutorFilter;
import org.apache.mina.filter.executor.OrderedThreadPoolExecutor;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.filter.util.ReferenceCountingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.mina.server.codec.MsgCodecFactory;

public class StartServer {

	static Logger log = Logger.getRootLogger();

	// private static Logger log = LoggerFactory.getLogger(SamplMinaServerHandler.class.getName());

	public void start(String localport) throws Exception {

		// 将log4j的配置文件log4j.properties放到config目录下，在这里指定位置
		String url = System.getProperty("user.dir") + File.separator + "config" + File.separator + "log4j.properties";
		
		//负责监视配置文件的更新情况,如果配置或者映射文件有更新
		PropertyConfigurator.configureAndWatch(url, 60);

		/*
		 * NioSocketAcceptor : the non-blocking Socket transport IoAcceptor
		 * NioDatagramAcceptor : the non-blocking UDP transport IoAcceptor
		 * AprSocketAcceptor : the blocking Socket transport IoAcceptor, based on APR
		 * VmPipeSocketAcceptor : the in-VM IoAcceptor
		 */
		// 初始化服务端的TCP/IP 的基于NIO 的套接字
		IoAcceptor acceptor = new NioSocketAcceptor();

		// 这个方法设置写操作的超时时间
		acceptor.getSessionConfig().setWriteTimeout(1000); 
				
		// 取出当前服务内创建新IoSession对象使用的默认配置,获得IoSessionConfig对象
		IoSessionConfig isc = acceptor.getSessionConfig();

		// 设置读取数据的缓冲区大小
		isc.setReadBufferSize(2048);

		// 读写通道均在120 秒内无任何操作就进入空闲状态
		isc.setIdleTime(IdleStatus.BOTH_IDLE, 120);
		
		
		// 创建接收数据的过滤器
		DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();

		//创建一个可根据需要创建新线程的线程池
		OrderedThreadPoolExecutor executor = new OrderedThreadPoolExecutor();

		// 设置日志过滤器
		LoggingFilter lf = new LoggingFilter();
		chain.addLast("logger", lf);

		// 支持多线程
		chain.addLast("executorChinFilter", new ExecutorFilter(executor));

		// 使用编解码器
		chain.addLast("decoderFilter", new ProtocolCodecFilter(
				new MsgCodecFactory(Charset.forName("UTF-8"))));

		// 设置输出时像BufferedOutputStream 一样进行缓冲。
		//chain.addLast("streamFilter", new BufferedWriteFilter());

		 //我自己加的过滤器。这个类现在没用上，以后再加，应该用于判断数据合法性
		 chain.addLast("ServerIOFilter", new ReferenceCountingFilter(
		 new MinaServerIOFilter()));
		 

		// 设定服务器端的消息处理器
		acceptor.setHandler(new MinaServerIOHandler());

		// 服务器端绑定的端口
		int bindPort = Integer.parseInt(localport);

		// 绑定端口,启动服务器
		acceptor.bind(new InetSocketAddress(bindPort));

		log.info("数据服务器已启动,当前端口号: " + bindPort);
	}
	
	public void listenClose() throws Exception {
		
	}

}